package family.console;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

import family.console.Person.Gender;



/**
 * This is the main class which contains all methods.
 * 
 * @author Edis Dilji
 * @version 3.0, November 4, 2012
 */

//CLASSDEFINITION
public class Main {

	//CONSTRUCTOR
	public Main() {
	}

	// MAIN-METHOD
	// main-method create only the first object and start the help-method,
	// which show all possible commands with explanation
	public static void main(String[] args) {
		//create new
		Main mm = new Main();
		mm.help();
	}

	// create HashMap 'people' - where all family member will be saved
	// key is the name of the person as a String
	private HashMap<String, Person> people = new HashMap<String, Person>();

	// METHOD begin
	public void begin() {

		// input contains what the user have entered
		String input = "";
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

		do {
			// show user which commands he can use
			System.out.println();
			System.out.println("Enter add <name>, gp <name>, pt <name>, cl <name>, all, help or stop:");
			try {
				
				// put entered to input
				input = bf.readLine();
				
				// separate the input by space character
				String[] separate = input.split(" ");

				// verify if input is 'add' and start the 'addPerson' method
				if (separate[0].equals("add")) {
					// if user only 'add' entered, start 'addPerson' method again
					if (separate.length == 1) {
						System.out.println("For add <name>, please enter a name...");
					} else {
						addPerson(separate[1]);
					}
					
				// verify if input is 'gp' and start the 'showGrandparents' method
				} else if (separate[0].equals("gp")) {
					// if user only 'add' entered, start 'showGrandparents' method again
					if (separate.length == 1) {
						System.out.println("For gp <name>, please enter a name...");
					} else {
						showGrandparents(people, separate[1]);
					}
					
				// verify if input is 'pt' and start the 'showParents' method
				} else if (separate[0].equals("pt")) {
					// if user only 'pt' entered, start 'showParents' method again
					if (separate.length == 1) {
						System.out.println("For pt <name>, please enter a name...");
					} else {
						showParents(people, separate[1]);
					}
					
				// verify if the input is 'cl' and start the 'showChildren' method
				} else if (separate[0].equals("cl")) {
					// if user only 'cl' entered, start 'showChildren' method again
					if (separate.length == 1) {
						System.out.println("For cl <name>, please enter a name...");
					} else {
						showChildren(people, separate[1]);
					}
					
				// verify if the input is 'all' and start the 'printAll' method
				} else if (separate[0].equals("all")) {
					printAll(people);
					
				// verify if the input is 'help' and start the 'help' method
				} else if (separate[0].equals("help")) {
					help();
					
				// verify if the input is 'stop' and go out
				} else if (separate[0].equals("stop")) {
					break;
					
				// verify if user has nothing entered and begin again
				} else if (separate[0].equals("")) {
					System.out.println("You have nothing entered, please enter an valid value...");
					begin();
					
				// if user enter a not valid value
				} else {
					System.out.println("Please enter an valid value");
				}
				
			// if catch exception, begin again the method	
			} catch (IOException e) {
				System.out.println("Please check your entry and try it again.");
				System.out.println("Error: " + e.toString());
				begin();
			}

		// exit the program and show this to the user
		} while (!(input.equals("stop")));
		System.out.println("The program has successfully stopped!");
		System.exit(0);

	}

	// METHOD addPerson - put family members to people
	public void addPerson(String name) {

		// input contains what the user have entered
		String input = "";
		Gender gender = null;
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

		try {
			
			// user have to enter the gender of the new person
			System.out.println("Enter gender ('m' for male or 'f' for female):");

			// loop while user enter 'm' or 'f' for gender
			do {
				input = bf.readLine();

				// if input 'm', set gender to male and go out
				if (input.equals("m")) {
					gender = Gender.male;
					break;
					
				// if input 'f', set gender to female and go out
				} else if (input.equals("f")) {
					gender = Gender.female;
					break;
					
				// if user entered something other
				} else {
					System.out.println("You entered '" + input
							+ "', please enter 'm' or 'f':");
				}
			} while (!(input.equals("m")) || !(input.equals("f")));

			// create new person
			Person person = new Person(name, gender);
			
			// put the person to people
			people.put(name, person);

			// add father and verify gender
			String fathername = "";
			boolean checkf = false;
			
			do {
				System.out.println("Enter " + name + "'s fathers name or leave empty: ");
				fathername = bf.readLine();
				Person father = people.get(fathername);

				// verify if entered father is male
				if (father != null) {
					if (father.getGender() != Gender.male) {
						System.out.println(fathername + " is not male, please verify your entry and try it again...");
						checkf = true;
					} else {
						// if entered father is male, set father of the person
						person.setFather(father);
						checkf = false;
					}
				}

			} while (checkf == true);

			// add mother and verify gender
			String mothername = "";
			boolean checkm = false;
			do {
				System.out.println("Enter " + name + "'s mothers name or leave empty: ");
				mothername = bf.readLine();
				Person mother = people.get(mothername);

				// verify if entered mother is female
				if (mother != null) {
					if (mother.getGender() != Gender.female) {
						System.out.println(mothername + " is not female, please verify your entry and try it again...");
						checkm = true;
					} else {
						// if entered mother is female, set mother of the person
						person.setMother(mother);
						checkm = false;
					}
				}

			} while (checkm == true);
			
		// if catch exception, go to begin-method
		} catch (Exception e) {
			System.out.print("Something is not ok, - ");
			System.out.println("error: " + e.toString());
			System.out.println("Let us start again...");
			begin();
		}

		// go to begin-method
		begin();
	}

	// METHOD showGrandparents - print the grandparents of the person
	public void showGrandparents(HashMap<String, Person> people, String name) {

		try {

			// loop all people
			for (Person p : people.values()) {

				// verify if the entered name is a member of the family
				if (p.getName().equals(name)) {

					// get the father of the person
					Person father = p.getFather();
					// get the mother of the person
					Person mother = p.getMother();

					System.out.println("The grandparents of " + name + " are: ");

					// verify if the entered person has a father and grandfather from fathersite
					if ((father != null && father.father != null)) {
						System.out.println(" - " + name + "'s grandfather (" + father.getName() + "'s father): " + p.father.father.getName());
					} else {
						System.out.println(" - " + name + "'s grandfather (" + father.getName() + "'s father): is not entered...");
					}
					// verify if the entered person has a father and grandmother from fathersite
					if ((father != null && father.mother != null)) {
						System.out.println(" - " + name + "'s grandmother (" + father.getName() + "'s mother): " + p.father.mother.getName());
					} else {
						System.out.println(" - " + name + "'s grandmother (" + father.getName() + "'s mother): is not entered...");
					}
					// verify if the entered person has a mother and grandfather from mothersite
					if ((mother != null && mother.father != null)) {
						System.out.println(" - " + name + "'s grandfather (" + mother.getName() + "'s father): " + p.mother.father.getName());
					} else {
						System.out.println(" - " + name + "'s grandfather (" + mother.getName() + "'s father): is not entered...");
					}
					// verify if the entered person has a mother and grandmother from mothersite
					if ((mother != null && mother.mother != null)) {
						System.out.println(" - " + name + "'s grandmother (" + mother.getName() + "'s mother): " + p.mother.mother.getName());
					} else {
						System.out.println(" - " + name + "'s grandmother (" + mother.getName() + "'s mother): is not entered...");
					}
				}
			}
			
		// if catch exception, go to begin-method
		} catch (Exception e) {
			System.out.print("Something is not ok, - ");
			System.out.println("error: " + e.toString());
			System.out.println("Let us start again...");
			begin();
		}

		// go to begin-method
		begin();
	}

	// METHOD showParents - print the parents of the person
	public void showParents(HashMap<String, Person> people, String name) {

		// loop all people
		for (Person p : people.values()) {
			
			// verify if the entered name is a member of the family
			if (p.getName().equals(name)) {

				// verify as if person has a mother and a father and print them
				if ((p.getMother() != null) && (p.getFather() != null)) {
					System.out.println("The parents of " + name + " are: ");
					System.out.println(" - " + name + "'s mother is " + p.getMother().getName());
					System.out.println(" - " + name + "'s father is " + p.getFather().getName());
					
				// verify as if person has only a mother and and print her
				} else if ((p.getMother() != null)) {
					System.out.println(name + "'s mother is " + p.getMother().getName());
					
				// verify as if person has only a father and and print him
				} else if ((p.getFather() != null)) {
					System.out.println(name + "'s father is " + p.getFather().getName());
				
				// if the person has no parents
				} else {
					System.out.println("The parents of " + name + " are not entered...");
				}

			}
		}

		// go to begin-method
		begin();
	}

	// METHOD showChildren - print the children of the person
	public void showChildren(HashMap<String, Person> people, String name) {

		System.out.print(name + "'s Children are: ");

		// loop all people
		for (Person p : people.values()) {
			
			// get the father of the person
			Person father = p.getFather();
			// get the mother of the person
			Person mother = p.getMother();

			// verify as if person has a father or a mother and equals the entered name and print it
			if ((father != null && father.getName().equals(name)) || (mother != null && mother.getName().equals(name))) {
				System.out.print(p.getName() + ", ");
			}
		}
		System.out.println("");
		
		// go to begin-method
		begin();
	}

	// METHOD printAll - print all family members
	public void printAll(HashMap<String, Person> people) {

		System.out.println("All people who have been entered are: ");

		// loop all people and print them
		for (Person p : people.values()) {
			System.out.println(" - " + p);
		}

		// go to begin-method
		begin();
	}

	// METHOD help - print all valid commands and go to the begin-method
	public void help() {
		// print all the valid commands with explanation 'add <name>', 'gp <name>', 'pt <name>', 
		// 'cl <name>', 'all', 'help' or 'stop'
		System.out.println("");
		System.out.println(" *****************************************************************");
		System.out.println(" *     Enter one of the following                                *");
		System.out.println(" *        add <name> - add a new person to the family            *");
		System.out.println(" *        gp <name>  - print the grandparents...                 *");
		System.out.println(" *        pt <name>  - print the parents...                      *");
		System.out.println(" *        cl <name>  - print the children...                     *");
		System.out.println(" *        all        - print all people who have been entered    *");
		System.out.println(" *        help       - print the valid inputs                    *");
		System.out.println(" *        stop       - end the program                           *");
		System.out.println(" *     Note: start with the OLDEST person and                    *");
		System.out.println(" *     use first names only, no spaces                           *");
		System.out.println(" *****************************************************************");
		
		// go to begin-method
		begin();
	}

}
